﻿#include "pch.h"

CResInfWrapper::CResInfWrapper()
{
    memset((void *)this, 0, sizeof(CResInfWrapper));
};

void CResInfWrapper::printSelf(char *captionUpper, int32_t)
{
    char caption[1024];
    sprintf(caption, "%s:%s", captionUpper, "CResInfWrapper");
    print4x(this, sizeof(CResInfWrapper), caption);
    if (this->head)
    {
        sprintf(caption, "%s:%s", captionUpper, "CResInfWrapper.head");
        print4x(this->head, this->size * this->len, caption);
    }
    if (this->num)
    {
        sprintf(caption, "%s:%s", captionUpper, "CResInfWrapper.num");
        print4x(this->num, sizeof(int32_t), caption);
    }
    if (this->rawbagFreq)
    {
        sprintf(caption, "%s:%s", captionUpper, "CResInfWrapper.rawbagFreq");
        print4x(this->rawbagFreq, sizeof(float), caption);
    }
}

// sub_1001D270
CResInfWrapper *CResInfWrapper::init(TDLLRESINF *resInf)
{
    this->init(resInf->head, (int32_t)resInf->len, (int32_t *)resInf->num);
    this->xMinUnitK = 60.0;
    this->rawbagFreq = NULL;
    return this;
};

// sub_1001DE60
CResInfWrapper *CResInfWrapper::init(TDLLResultListItem *head, int32_t len, int32_t *num)
{
    this->head = (LPVOID)head;
    this->size = 184;
    this->len = len;
    this->tail = 0;
    this->needFreeHead = false;
    this->num = num;
    return this;
};

// sub_1001A9D0
void CResInfWrapper::increaseNum(int32_t incNum)
{
    int32_t *numPointer; // edx

    if (incNum >= 0)
    {
        numPointer = this->getNumPointer();
        *numPointer += incNum;
    }
};

// sub_10022270
int32_t CResInfWrapper::filterOutInvalidTr(TDLLResultListItem *pRes, int32_t loopCount)
{
    int32_t offset;
    int32_t i;
    int32_t len;

    len = this->getLen();
    offset = (int32_t)((int64_t)pRes - (int64_t)this->head) / sizeof(TDLLResultListItem);
    i = 0;
    while (i <= loopCount)
    {
        if (pRes[i].tr)
        {
            ++i;
        }
        else
        {
            --loopCount;
            memcpy((void *)&pRes[i], (const void *)&pRes[i + 1], sizeof(TDLLResultListItem) * (len - offset - i - 1));
            memset((void *)&pRes[len - offset - 1], 0, sizeof(TDLLResultListItem));
        }
    }
    return loopCount;
};

// sub_1002201E
int32_t CResInfWrapper::calcW50etcAll(TDLLResultListItem *pRes, int32_t tail, int32_t *smpHead, float freq)
{
    int32_t result = 0;
    int32_t i;

    for (i = 0; i <= tail; ++i)
    {
        calcW50etc(&pRes[i], this->head, smpHead, freq, this->xMinUnitK);
        result = i + 1;
    }
    return result;
};

// sub_100206EB
int32_t CResInfWrapper::cleanIdnoNameEtc()
{
    int32_t result;
    int32_t i;

    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    for (i = 0;; ++i)
    {
        result = i;
        if (i >= *this->num)
        {
            break;
        }
        pRes[i].Idno = 0;
        memset(&pRes[i].Name, 0, 0x20u);
        pRes[i].AreaPer = 0;
        pRes[i].Conc = 0;
    }
    return result;
};

// sub_1002078D
int32_t CResInfWrapper::calcAreaPer()
{
    int32_t i;
    double sumArea;

    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    sumArea = 0.0;
    if (!*this->num)
    {
        return false;
    }
    for (i = 0; i < *this->num; ++i)
    {
        sumArea = sumArea + pRes[i].Area;
    }
    if (sumArea >= 1.0)
    {
        for (i = 0; i < *this->num; ++i)
        {
            pRes[i].AreaPer = 100.0l * pRes[i].Area / sumArea;
        }
    }
    return true;
};

// sub_1001AF90
int32_t CResInfWrapper::setIdno(int32_t idx, int32_t idno)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    pRes[idx].Idno = idno;
    return 184 * idx;
};

// sub_1001AFC0
char *CResInfWrapper::setName(int32_t idx, char *name)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    snprintf((char *)pRes[idx].Name, sizeof(pRes[idx].Name), "%s", name);
    return pRes[idx].Name;
};

// sub_10022DF9
double CResInfWrapper::getInBandOutRTime(double idtTime, double band, int32_t based, double factor)
{
    int32_t idx;
    double rTime;

    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    rTime = 0.0;
    idx = this->getInBandOutIdex(idtTime, band, based, factor);
    if (idx >= 0)
    {
        rTime = pRes[idx].RTime;
    }
    return rTime;
};

// sub_10022C51
int32_t CResInfWrapper::getInBandOutIdex(double idtTime, double band, int32_t based, double factor)
{
    int32_t result;
    int32_t useTempIdx;
    int32_t prevOutIdx;
    int32_t currentOutIdx;
    int32_t i;
    int32_t outIdx;
    int32_t num;
    int32_t tempIdx;

    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    if (idtTime <= 0.0)
    {
        return -1;
    }
    num = *this->num;
    if (num <= 0)
    {
        return -1;
    }
    outIdx = -1;
    for (i = 0; i < num; ++i)
    {
        if (pRes[i].RTime > idtTime)
        {
            outIdx = i;
            break;
        }
    }
    if (outIdx > 0)
    {
        currentOutIdx = -1;
        prevOutIdx = -1;
        if (this->isIdtRtimeInBands(outIdx, idtTime, band, factor))
        {
            currentOutIdx = outIdx;
        }
        if (this->isIdtRtimeInBands(outIdx - 1, idtTime, band, factor))
        {
            prevOutIdx = outIdx - 1;
        }
        if (currentOutIdx >= 0 && prevOutIdx >= 0)
        {
            return this->getAOptimalIdx(idtTime, based, currentOutIdx, prevOutIdx);
        }
        if (currentOutIdx >= 0)
        {
            return currentOutIdx;
        }
        if (prevOutIdx < 0)
        {
            return -1;
        }
        return prevOutIdx;
    }
    if (outIdx >= 0)
    {
        tempIdx = 0;
        useTempIdx = this->isIdtRtimeInBands(0, idtTime, band, factor);
    }
    else
    {
        tempIdx = num - 1;
        useTempIdx = this->isIdtRtimeInBands(num - 1, idtTime, band, factor);
    }
    if (useTempIdx)
    {
        result = tempIdx;
    }
    else
    {
        result = -1;
    }
    return result;
};

// sub_10022871
int32_t CResInfWrapper::isIdtRtimeInBands(int32_t idx, double idtTime, double band, double factor)
{
    double tRight;
    double tLeft;
    double rTime;

    tLeft = 0.0;
    tRight = 0.0;
    rTime = this->fetchResultRTime(idx, &tLeft, &tRight, factor);
    return isRTimeInBands(idtTime, band, rTime, tLeft, tRight);
};

// sub_1002273F
double CResInfWrapper::fetchResultRTime(int32_t idx, double *tLeft, double *tRight, double factor)
{
    double tLeftOption;
    double tRightOption;
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    if (factor <= 0.0)
    {
        *tLeft = 0;
        *tRight = 0;
    }
    else
    {
        tLeftOption = this->getALeftProportion(idx) * factor;
        *tLeft = (pRes[idx].tr - this->getTsOrPrevTe(idx)) / *this->rawbagFreq / this->xMinUnitK;
        if (*tLeft > tLeftOption && tLeftOption > 0.0)
        {
            *tLeft = tLeftOption;
        }
        tRightOption = this->getARightProportion(idx) * factor;
        *tRight = (this->getTeOrNextTs(idx) - pRes[idx].tr) / *this->rawbagFreq / this->xMinUnitK;
        if (*tRight > tRightOption && tRightOption > 0.0)
        {
            *tRight = tRightOption;
        }
    }
    return pRes[idx].RTime;
};

// sub_10022665
double CResInfWrapper::getALeftProportion(int32_t idx)
{
    double dVal;
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    if (pRes[idx].Area <= 0.0)
    {
        dVal = 0.0;
    }
    else
    {
        dVal = pRes[idx].ALeft / pRes[idx].Area * pRes[idx].Sigma5 / 5.0;
    }
    return dVal;
};

// sub_1002255F
double CResInfWrapper::getTsOrPrevTe(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    double dVal;

    dVal = pRes[idx].ts;
    if ((pRes[idx].TypeCode[0] & X7F) == C115 && idx > 0 && (pRes[idx - 1].TypeCode[0] & X7F) == C116)
    {
        dVal = pRes[idx - 1].te;
    }
    return dVal;
};

// sub_100226D2
double CResInfWrapper::getARightProportion(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    double dVal;

    if (pRes[idx].Area <= 0.0)
    {
        dVal = 0.0;
    }
    else
    {
        dVal = pRes[idx].ARight / pRes[idx].Area * pRes[idx].Sigma5 / 5.0;
    }
    return dVal;
};

// sub_100225DA
double CResInfWrapper::getTeOrNextTs(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    double dVal;

    dVal = pRes[idx].te;
    if ((pRes[idx].TypeCode[0] & X7F) == C83 && idx < *this->num - 1 && (pRes[idx + 1].TypeCode[0] & X7F) == C84)
    {
        dVal = pRes[idx].ts;
    }
    return dVal;
};

// sub_10022B4A
int32_t CResInfWrapper::getAOptimalIdx(double ceilRTime, int32_t basedOn, int32_t idx, int32_t newIdx)
{
    int32_t result;
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    result = idx;
    if (newIdx >= 0 && newIdx < *this->num)
    {
        if (basedOn)
        {
            if (basedOn == 1)
            {
                if (pRes[newIdx].Height > pRes[idx].Height)
                {
                    result = newIdx;
                }
            }
            else
            {
                if (fabs(ceilRTime - pRes[newIdx].RTime) < fabs(ceilRTime - pRes[idx].RTime))
                {
                    result = newIdx;
                }
            }
        }
        else if (pRes[newIdx].Area > pRes[idx].RTime)
        {
            result = newIdx;
        }
    }
    return result;
};

// sub_1001AC40
int32_t CResInfWrapper::getIdno(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    return pRes[idx].Idno;
};

// sub_1001ACC0
double CResInfWrapper::getArea(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    return pRes[idx].Area;
};

// sub_1001ACE0
double CResInfWrapper::getHeight(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    return pRes[idx].Height;
};

// sub_1001B030
char *CResInfWrapper::setIdnoAndName(int32_t idx, int32_t idno, char *name)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    pRes[idx].Idno = idno;
    strncpy(pRes[idx].Name, name, 0x1Fu);
    return pRes[idx].Name;
};

// sub_1001AC80
double CResInfWrapper::getAreaOrHeight(int32_t bArea, int32_t idx)
{
    double result;

    if (bArea)
    {
        result = this->getArea(idx);
    }
    else
    {
        result = this->getHeight(idx);
    }
    return result;
};

// sub_1001AC10
int32_t CResInfWrapper::setConc(int32_t idx, double conc)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    pRes[idx].Conc = conc;
    return 184 * idx;
};

// sub_100223CC
double CResInfWrapper::getAreaOrHeightByIdno(int32_t onArea, int32_t idno)
{
    double result;
    int32_t i;
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;

    for (i = 0;; ++i)
    {
        if (i >= *this->num)
        {
            return 0.0;
        }
        if (pRes[i].Idno == idno)
        {
            break;
        }
    }
    if (onArea)
    {
        result = pRes[i].Area;
    }
    else
    {
        result = pRes[i].Height;
    }
    return result;
};

// sub_1001AC60
double CResInfWrapper::getConc(int32_t idx)
{
    TDLLResultListItem *pRes = (TDLLResultListItem *)this->head;
    return pRes[idx].Conc;
};

// sub_100220B1
int32_t CResInfWrapper::filterOutInvalidItem(TDLLResultListItem *pRes, int32_t tail, int32_t minHeight, int32_t minArea, char flag, int32_t *zero)
{
    int32_t freeCount;
    int32_t i;
    int32_t len;

    len = this->getLen();
    freeCount = (int32_t)((int64_t)pRes - (int64_t)this->head) / sizeof(TDLLResultListItem);
    if (zero)
    {
        *zero = 0;
    }
    i = 0;
    while (i <= tail)
    {
        if (invalidAreaAndHeight(&pRes[i], minArea, minHeight, flag))
        {
            --tail;
            memcpy((void *)&pRes[i], (const void *)&pRes[i + 1], sizeof(TDLLResultListItem) * (len - freeCount - i - 1));
            memset((void *)&pRes[len - freeCount - 1], 0, sizeof(TDLLResultListItem));
        }
        else
        {
            ++i;
        }
    }
    return tail;
};

// sub_1001DCD0
int32_t CResInfWrapper::setXMinUnitK(TMiscellaneous *wParam)
{
    if (wParam)
    {
        this->xMinUnitK = wParam->XMinUnitK; //// 16,17 is error,should be 15,16
    }
    else
    {
        this->xMinUnitK = 60.0;
    }
    return true;
};
